#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_sdio.h>
#include <stm32f10x_usart.h>
#include <stdio.h> // 这个是MicroLib里面的头文件
#include <misc.h>
#define DELAY_COUNT 6

void delay_us(u32 x)
{
	u32 i = DELAY_COUNT;
	//大约999.3us STM32 72MHz
	/*
		i = 1000	83.68us  
		i = 11.9     
		i = 12 		1.34us   
		i = 11		1.25us  
		i = 10		1.17us
		i = 8 		1.22us
		i = 5		0.93us
		i = 6		1.03us
	*/

	while (x--)
	{
		//先测试一个整数，然后大体计算，真实循环的次数=MDK测试的时间（转换成us）/测试循环数，
		//如：x=1/[(0.00025512-0.00017144)*1000000/1000]=1024
		while (i--)
			;
		i = DELAY_COUNT;
	}
}

void uart_nvic_config()
{
	NVIC_InitTypeDef uart_nvic;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	uart_nvic.NVIC_IRQChannel = USART1_IRQn;
	uart_nvic.NVIC_IRQChannelCmd = ENABLE;
	uart_nvic.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级
	uart_nvic.NVIC_IRQChannelSubPriority = 0;		 // 子优先级

	NVIC_Init(&uart_nvic);
}

void uart_init()
{
	GPIO_InitTypeDef tx, rx;
	USART_InitTypeDef usart1;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //打开串口时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //打开GPIO口时钟

	//tx pa9
	tx.GPIO_Pin = GPIO_Pin_9;
	tx.GPIO_Mode = GPIO_Mode_AF_PP;
	tx.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &tx); //tx初始化
	//rx pa10
	rx.GPIO_Pin = GPIO_Pin_10;
	rx.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &rx); //rx初始化

	//usart1 参数配置
	usart1.USART_BaudRate = 9600;									   //波特率
	usart1.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //串口硬件流设置
	usart1.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;				   //串口收发模式使能
	usart1.USART_Parity = USART_Parity_No;							   //校验位
	usart1.USART_StopBits = USART_StopBits_1;						   //停止位
	usart1.USART_WordLength = USART_WordLength_8b;					   //字节长度
	USART_Init(USART1, &usart1);									   //串口参数初始化
	USART_Cmd(USART1, ENABLE);										   //串口使能

	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	uart_nvic_config();
}

void USART1_SendString(u8 *str)
{
	int i = 0;
	while (*(str + i))
	{
		// 一定要添加此语句，用于清楚标记，否则会导致当前缓冲区被忽略
		USART_ClearFlag(USART1, USART_FLAG_TC);
		// 每次发送前一定要有延时，即使添加了判断FLAG_TC位，如果直接发
		// 有的时候还是位有丢数据的情况，51单片机这种情况比较明显，stm32基本没有
		// 但是还是添加10ms用于确保发送
		delay_us(10);
		USART_SendData(USART1, *(str + i));

		while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
			;
		i++;
	}
}

int fputc(int ch, FILE *strewam)
{
	// USART1_SendString(USART1, (u16)ch);
	USART_ClearFlag(USART1, USART_FLAG_TC);
	delay_us(10);
	USART_SendData(USART1, (u8)ch);
	while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
		;

	return ch;
}



void USART1_IRQHandler()
{
	if (SET == USART_GetITStatus(USART1, USART_IT_RXNE))
	{
		USART_SendData(USART1, USART_ReceiveData(USART1));
	}

	USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}

int main(void)
{
	uart_init();
	// char *str = "Embeded develop";
	//u8 str[30] = "Embeded develop\r\n";
	// USART1_SendString(str);
	printf("Embeded develop\r\n");
	// uart_send_str(str);
	while (1)
		;
	//return 1;
}
